﻿using Blog.Core.Common.Helper;
using Blog.Core.IServices;
using Blog.Core.Model;
using Blog.Core.Model.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;

namespace Blog.Core.Api.Controllers
{
    //[Produces("application/json")]
    [Route("api/Novel/[action]")]
    [ApiController]
    public class NovelController : ControllerBase
    {
        readonly HttpClient http;
        private readonly ILogger<NovelController> _logger;
        public IbookServices _bookServices { get; set; }
        public IchapterServices _chapterServices { get; set; }
        string baseUrl = "https://www.xbiquge.la";
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger"></param>
        /// 
        public NovelController(ILogger<NovelController> logger)
        {
            _logger = logger;
            http = new HttpClient();
        }
        /// <summary>
        /// 查找小说
        /// </summary>
        /// <param name="searchkey"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<MessageModel<List<book>>> GetSearch(string searchkey)
        {
            var data = new MessageModel<List<book>>();
            List<book> books = new List<book>();
            string response = await HttpHelper.GetAsync(string.Format("{0}/modules/article/waps.php?searchkey={1}",baseUrl, searchkey));
            Regex rx = new Regex(@"<tr>[\s\S]*?</tr>");// 匹配所有a标签：<a\b[^>]+\bhref="([^"]*)"[^>]*>([\s\S]*?)</a>   <a[^>]*href=([""'])?(?<href>[^'""]+)\1[^>]*>
            MatchCollection matches = rx.Matches(response);
            rx = new Regex("<a .*?href=['\"](.*?)['\"].*?>(.*?)</a>");
            foreach (var tr in matches)
            {
                book book = new book();
                MatchCollection matchs = rx.Matches(tr.ToString());
                if (matchs.Count == 2)
                {
                    book.bName = matchs[0].Groups[2].Value;
                    book.url = matchs[0].Groups[1].Value;
                    book sysBook = (await _bookServices.Query(b => b.bName == book.bName && b.url == book.url)).FirstOrDefault();
                    if (sysBook == null)
                    {
                        string newBook = await HttpHelper.GetAsync(book.url);
                        Regex rx_book_name = new Regex("(?<=meta property=\"og:novel:book_name\" content=\").*?(?=\")");
                        Regex rx_author = new Regex("(?<=meta property=\"og:novel:author\" content=\").*?(?=\")");
                        Regex rx_image = new Regex("(?<=meta property=\"og:image\" content=\").*?(?=\")");
                        Regex rx_bcategory = new Regex("(?<=meta property=\"og:novel:category\" content=\").*?(?=\")");
                        Regex rx_description = new Regex("(?<=meta property=\"og:description\" content=\").*?(?=\")");
                        if (!string.IsNullOrEmpty(rx_book_name.Match(newBook).Value))
                        {
                            book.bName = rx_book_name.Match(newBook).Value;
                        }
                        if (!string.IsNullOrEmpty(rx_author.Match(newBook).Value))
                        {
                            book.bAuthor = rx_author.Match(newBook).Value;
                        }
                        if (!string.IsNullOrEmpty(rx_image.Match(newBook).Value))
                        {
                            book.coverImg = rx_image.Match(newBook).Value;
                        }
                        if (!string.IsNullOrEmpty(rx_bcategory.Match(newBook).Value))
                        {
                            book.category = rx_bcategory.Match(newBook).Value;
                        }
                        if (!string.IsNullOrEmpty(rx_description.Match(newBook).Value))
                        {
                            book.profiles = rx_description.Match(newBook).Value;
                        }
                        book.bState = 1;
                        try
                        {
                            string time = newBook.Substring(newBook.IndexOf("最后更新：") + 5, 19);
                            book.updateTime = Convert.ToDateTime(time);
                        }
                        catch (Exception) 
                        {
                            book.updateTime = DateTime.Now;
                        }

                        book.newChapter = "";

                        Regex rx1 = new Regex(@"<dd><a[^>]*href=([""'])?(?<href>[^'""]+)\1[^>]*>*.*</a></dd>");
                        MatchCollection matches1 = rx1.Matches(newBook);
                        for (int i = 0; i < matches1.Count; i++)
                        {
                            if(i== matches1.Count-1)
                                book.newChapter = rx.Match(matches1[i].ToString()).Groups[2].Value;
                        }

                        book.bId = 0;
                    }
                    else
                    {
                        book = sysBook;
                    }
                    books.Add(book);
                }
            }
            data.success = true;
            data.response = books;
            return data;
        }
        /// <summary>
        /// 获取小说章节目录
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<MessageModel<string>> GetCatalogue(string url)
        {
            var data = new MessageModel<string>();
            try
            {
                url = HttpUtility.UrlDecode(url);
                string response = await HttpHelper.GetAsync(url);
                book book = new book();
                // 匹配所有a标签目录 <dd><a[^>]*href=([""'])?(?<href>[^'""]+)\1[^>]*>*.*</a></dd>
                // 匹配封面图片      <div.*?id=\"fmimg\">(?<html>[\s\S]*?)</div>
                // 匹配书名称        <meta property="og:novel:book_name"(.*?)>
                // 匹配作者          <meta property="og:novel:author"(.*?)>
                // 匹配类型          <meta property="og:novel:category"(.*?)>
                // 匹配封面图片      <meta property="og:image"(.*?)>
                Regex rx_book_name = new Regex("(?<=meta property=\"og:novel:book_name\" content=\").*?(?=\")");
                Regex rx_author = new Regex("(?<=meta property=\"og:novel:author\" content=\").*?(?=\")");
                Regex rx_image = new Regex("(?<=meta property=\"og:image\" content=\").*?(?=\")");
                Regex rx_bcategory = new Regex("(?<=meta property=\"og:novel:category\" content=\").*?(?=\")");
                Regex rx_description = new Regex("(?<=meta property=\"og:description\" content=\").*?(?=\")");
                if (!string.IsNullOrEmpty(rx_book_name.Match(response).Value))
                {
                    book.bName = rx_book_name.Match(response).Value;
                }
                if (!string.IsNullOrEmpty(rx_author.Match(response).Value))
                {
                    book.bAuthor = rx_author.Match(response).Value;
                }
                if (!string.IsNullOrEmpty(rx_image.Match(response).Value))
                {
                    book.coverImg = rx_image.Match(response).Value;
                }
                if (!string.IsNullOrEmpty(rx_bcategory.Match(response).Value))
                {
                    book.category = rx_bcategory.Match(response).Value;
                }
                if (!string.IsNullOrEmpty(rx_description.Match(response).Value))
                {
                    book.profiles = rx_description.Match(response).Value;
                }
                book.bState = 1;
                book.url = url;
                book.updateTime = DateTime.Now;
                book bk = (await _bookServices.Query(b => b.bName == book.bName && b.bAuthor == book.bAuthor)).FirstOrDefault();
                if (bk == null)
                {
                    book.bId = await _bookServices.Add(book);
                }
                else
                {
                    book = bk;
                }
                Regex rx = new Regex(@"<dd><a[^>]*href=([""'])?(?<href>[^'""]+)\1[^>]*>*.*</a></dd>");
                MatchCollection matches = rx.Matches(response);
                rx = new Regex("<a .*?href=['\"](.*?)['\"].*?>(.*?)</a>");
                List<chapter> chapters = await _chapterServices.Query(c => c.bId == book.bId);
                foreach (var item in matches)
                {
                    string href = rx.Match(item.ToString()).Groups[1].Value;
                    string text = rx.Match(item.ToString()).Groups[2].Value;
                    List<chapter> cs = chapters.Where(c => c.cName == text || c.url == href).ToList();
                    if (cs.Count == 0)
                    {
                        chapter chapter = new chapter();
                        chapter.bId = book.bId;
                        chapter.cName = text;
                        chapter.url = href;
                        chapter.updateTime = DateTime.Now;
                        chapter.cId = await _chapterServices.Add(chapter);
                    }
                }
                chapters = await _chapterServices.Query(c => c.bId == book.bId, " cId asc ");
                chapters = chapters.Where(c => c.cContent == null).ToList();
                for (int i = 0; i < chapters.Count; i++)
                {
                    string content = await HttpHelper.GetAsync(baseUrl + chapters[i].url);
                    Regex rx_content = new Regex("<div.*?id=\"content\">(?<html>[\\s\\S]*?)</div>");
                    Match match = rx_content.Match(content);
                    chapters[i].cContent = match.Value;
                    await _chapterServices.Update(chapters[i]);
                    if (i == chapters.Count - 1)
                    {
                        book.newChapter = chapters[i].cName;
                        book.updateTime = DateTime.Now;
                        await _bookServices.Update(book);
                    }
                }
                data.success = true;
            }
            catch(Exception ex)
            {
                data.success = false;
                data.msg = "失败！原因：" + ex.Message;
            }
            return data;
        }
        /// <summary>
        /// 获取章节目录信息
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<MessageModel<string>> GetChapterLogInfo(string url)
        {
            url = HttpUtility.UrlDecode(url);
            var data = new MessageModel<string>();
            string response = await HttpHelper.GetAsync(url);
            Regex rx = new Regex("<div.*?id=\"content\">(?<html>[\\s\\S]*?)</div>");
            Match match = rx.Match(response);
            data.msg = match.Value;
            return data;
        }
        /// <summary>
        /// 获取章节信息
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<MessageModel<string>> GetChapterInfo(string url)
        {
            url = HttpUtility.UrlDecode(url);
            var data = new MessageModel<string>();
            string response = await HttpHelper.GetAsync(url);
            Regex rx = new Regex("<div.*?id=\"content\">(?<html>[\\s\\S]*?)</div>");
            Match match = rx.Match(response);
            data.msg = match.Value;
            return data;
        }
    }
}
